import { PrismaClientExceptionFilter, PrismaModule, PrismaService } from 'nestjs-prisma'
import i18n from '@/i18n'
import { AppLogger } from '@libs/lhy-common'
import { Module, OnModuleDestroy } from '@nestjs/common'
import { APP_FILTER, HttpAdapterHost } from '@nestjs/core'
import { CoreConfigService } from '../core-config'

@Module({
  imports: [
    // prisma配置
    PrismaModule.forRootAsync({
      isGlobal: true,
      useFactory(configService: CoreConfigService) {
        return {
          prismaOptions: {
            datasources: {
              db: {
                url: configService.config.database.url,
              },
            },
            log: [
              {
                emit: 'event',
                level: 'query',
              },
              {
                emit: 'event',
                level: 'info',
              },
              {
                emit: 'event',
                level: 'warn',
              },
              {
                emit: 'event',
                level: 'error',
              },
            ],
          },
          middlewares: [
            (param, next) =>
              next(param).then(data => {
                AppLogger.info(CoreDatabaseModule.name, () =>
                  i18n.t('lhy-core.core-database.core-database.1214831-0', { args: [JSON.stringify(data)] })
                )
                return data
              }),
          ],
          explicitConnect: false,
        }
      },
      inject: [CoreConfigService],
    }),
  ],
  providers: [
    {
      provide: APP_FILTER,
      useFactory(host: HttpAdapterHost) {
        return new PrismaClientExceptionFilter(host.httpAdapter)
      },
      inject: [HttpAdapterHost],
    },
  ],
  exports: [PrismaModule],
})
export class CoreDatabaseModule implements OnModuleDestroy {
  constructor(readonly prismaService: PrismaService) {
    prismaService.$on('query', e => {
      AppLogger.info(CoreDatabaseModule.name, () =>
        i18n.t('lhy-core.core-database.core-database.1214831-1', { args: [e.query, e.params, e.duration] })
      )
    })

    prismaService.$on('info', e => {
      AppLogger.info(CoreDatabaseModule.name, () => e.message)
    })

    prismaService.$on('warn', e => {
      AppLogger.warn(CoreDatabaseModule.name, () => e.message)
    })

    prismaService.$on('error', e => {
      AppLogger.error(CoreDatabaseModule.name, () => e.message)
    })
  }

  onModuleDestroy() {
    // 确保数据库连接关闭
    this.prismaService.$disconnect()
  }
}
